<template>
  <el-dialog
    title="数据集管理"
    :visible.sync="sqlDataSetValue.dialogVisible"
    append-to-body
    :close-on-click-modal="false"
    width="1140px"
  >
    <el-container>
      <el-header style="height: 40px">
        <el-input v-model="searchTableName" size="mini" placeholder="搜索表" style="width: 270px;">
          <el-button slot="append" icon="el-icon-search" @click="searchTable" />
        </el-input>
        <label>
          <font style="color: red;margin-left: 10px;">*</font>数据集名称：
        </label>
        <el-input v-model="dataSetName" size="mini" style="width: 320px;" />
        <div style="display: inline-block;float: right;">
          <el-button type="primary" size="mini" plain @click="addDataSetParam">参数配置</el-button>
          <el-button type="primary" size="mini" icon="el-icon-video-play" @click="previewData">运行</el-button>
          <el-button type="primary" size="mini" @click="saveDataSet">确认编辑</el-button>
        </div>
      </el-header>
      <el-container>
        <el-aside width="270px" style="height: 550px;">
          <div style="padding: 5px 0px;border-radius: 3px;border: 1px solid #DCDFE6;height: 550px;overflow: auto;" draggable="false" class="dataset-table el-tree-node is-focusable">
            <el-scrollbar style="height: 100%">
              <div v-for="item in searchTableNameList" class="el-tree-node__content" @dblclick="addTable(item.name)">
                <span class="el-tree-node__expand-icon" />
                <span class="el-tree-node__label">{{ item.name }}</span>
              </div>
            </el-scrollbar>
          </div>
        </el-aside>
        <el-main style="padding-left: 10px;padding-top: 0px;">
          <textarea ref="sqlexpressioncode" value="" />
          <el-tabs v-model="activeName">
            <el-tab-pane label="信息" name="first">
              <div style="height: 200px;">
                <div v-for="(m,index) in message" :key="index+1"> {{ m }} </div>
              </div>
            </el-tab-pane>
            <el-tab-pane name="second">
              <span slot="label">
                查询结果
                <el-tooltip class="item" effect="dark" content="仅显示前100条数据" placement="top">
                  <i class="el-icon-info" />
                </el-tooltip>
              </span>
              <el-table border :data="tableData.data" size="mini" height="200">
                <template v-for="column in tableData.columns">
                  <el-table-column :key="column" :prop="column" :label="column" :show-overflow-tooltip="true" min-width="180px" />
                </template>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-main>
      </el-container>
      <data-set-parameter-dialog :data-set-parameter-value="dataSetParameterValue" />
    </el-container>
  </el-dialog>
</template>

<script>
import DataSetParameterDialog from './DataSetParameterDialog'
import CodeMirror from 'codemirror'
import 'codemirror/theme/material-darker.css'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/addon/hint/sql-hint.js'
import { previewData, selectDruidList, selectDruidTableList, selectDruidTableFieldList } from '@/api/datasource'

export default {
  components: {
    DataSetParameterDialog
  },
  props: {
    sqlDataSetValue: {
      type: Object,
      required: true
    },
    refresh: {
      type: Function,
      required: true
    }
  },
  data: function() {
    return {
      activeName: 'first',
      druidList: [],
      druid: {},
      druidCode: '',
      tableNameList: [],
      searchTableName: '',
      searchTableNameList: [],
      parameters: [],
      dataSetName: '',
      sql: '',
      dataSetParameterValue: {
        dialogVisible: false
      },
      message: [],
      tableData: {
        data: [],
        columns: []
      }
    }
  },
  watch: {
    sqlDataSetValue: function(val) {
      this.init(val)
    }
  },
  mounted: function() {
    this.init(this.sqlDataSetValue)
  },
  methods: {
    init(val) {
      if (val.context && val.context.reportDef) {
        selectDruidList({}).then(res => {
          this.druidList = res.data || []
        })
        this.initEditor()
        this.message = []
        this.tableData.data = []
        this.tableData.columns = []
        this.searchTableNameList = []
        this.druidCode = val.code
        this.selecteDruid(val.code)
        if (val.edit) {
          const dataset = val.dataset
          this.dataSetName = dataset.name
          this.sql = dataset.sql
          this.parameters = dataset.parameters
        } else {
          this.dataSetName = ''
          this.sql = ''
          this.parameters = []
        }
      }
    },
    initEditor() {
      const that = this
      this.$nextTick(() => {
        if (!this.editor) {
          this.editor = CodeMirror.fromTextArea(this.$refs.sqlexpressioncode, {
            mode: 'text/x-sql',
            lineNumbers: true,
            theme: 'material-darker',
            gutters: ['CodeMirror-linenumbers', 'CodeMirror-lint-markers'],
            lint: {
              async: true
            },
            extraKeys: {
              'Ctrl': 'autocomplete'
            },
            matchBrackets: true,
            autofocus: true,
            hintOptions: {
              tables: {},
              completeSingle: false
            }
          })
          this.editor.setSize('820px', '300px')
          this.editor.on('change', function(cm, changes) {
            const expr = cm.getValue()
            that.sql = expr
          })
          this.editor.on('inputRead', function(codeMirror, object) {
            if (object.text[0] !== ' ') {
              that.editor.showHint()
            }
          })
        }
        this.editor.setValue(this.sql)
      })
    },
    selecteDruid(val) {
      selectDruidTableList({ dataSourceCode: val }).then(res => {
        this.tableNameList = res.data
        this.searchTableNameList = res.data
      })
    },
    searchTable() {
      const tables = []
      for (const item of this.tableNameList) {
        const searchTableName = this.searchTableName.toLowerCase()
        if (item.name.indexOf(searchTableName) > -1) {
          tables.push(item)
        }
      }
      this.searchTableNameList = tables
    },
    addTable(name) {
      this.editor.setValue('select * from ' + name)
    },
    addDataSetParam() {
      this.dataSetParameterValue = {
        dialogVisible: true,
        edit: false,
        parameters: this.parameters
      }
    },
    previewData() {
      if (!this.sql) {
        this.$message('请添加查询SQL语句')
        return
      }
      const param = {
        dataSourceCode: this.druidCode,
        name: '',
        sql: this.sql,
        parameters: this.parameters
      }
      previewData(param).then(res => {
        const ms = []
        ms.push(res.sql)
        ms.push(res.message || 'OK')
        if (!res.message) {
          this.activeName = 'second'
        } else {
          this.activeName = 'first'
        }
        let arr = []
        if (res.data && res.data.length > 100) {
          arr = res.data.splice(0, 100)
        } else {
          arr = res.data || []
        }
        this.message = ms
        this.tableData = {
          data: arr,
          columns: res.fields || []
        }
      })
    },
    saveDataSet() {
      if (!this.sql) {
        this.$message('请添加查询SQL语句')
        return
      }
      if (!this.dataSetName) {
        this.$message('请输入数据集名称')
        return
      }
      const epx = /^[\d-]/
      if (epx.test(this.dataSetName)) {
        this.$message('名称不能是数字开头')
        return
      }
      const param = {
        dataSourceCode: this.druidCode,
        name: this.dataSetName,
        sql: this.sql,
        parameters: this.parameters
      }
      const datasources = this.sqlDataSetValue.context.reportDef.datasources
      for (const index in datasources) {
        const datasource = datasources[index]
        const datasets = datasource.datasets
        const old = datasets.find(ele => ele.name === param.name)
        if (old && !this.sqlDataSetValue.edit) {
          this.$message('数据集名称重复')
          return
        }
      }
      selectDruidTableFieldList(param).then(res => {
        const data = res.data
        const newDataSet = {
          name: param.name,
          sql: param.sql,
          parameters: param.parameters,
          fields: data
        }
        const ds = datasources.find(ele => { return ele.code === param.dataSourceCode })
        if (this.sqlDataSetValue.edit) {
          for (const index in ds.datasets) {
            const d = ds.datasets[index]
            if (d.name === this.sqlDataSetValue.dataset.name) {
              ds.datasets.splice(index, 1, newDataSet)
            }
          }
        } else {
          ds.datasets.push(newDataSet)
        }
        // this.refresh(this.sqlDataSetValue)
        this.sqlDataSetValue.dialogVisible = false
      })
    }
  }
}
</script>

<style>
  .CodeMirror-hints {
    z-index: 3000 !important;
  }

  .dataset-table .el-tree-node__label {
    max-width: 230px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis
  }

  .dataset-table .el-scrollbar__wrap {
    overflow-x: hidden;
  }
</style>
